let nfcAdapter = null;
let nfcMain = null;

/**
 * 初始化NFC适配器
 * @returns {boolean} 如果初始化成功，返回true；否则返回false
 * @throws {string} 初始化失败时抛出错误信息
 */
function initNfc() {
  const systemInfo = uni.getSystemInfoSync();
  const platform = systemInfo.platform;
  const system = systemInfo.system;
  // console.log("当前平台:", platform);
  // console.log("系统版本:", system);

  // 检查是否在App环境
  if (platform !== "android" && platform !== "ios") {
    throw new Error("非移动设备平台，不支持NFC");
  }

  // 检查系统版本
  if (platform === "android") {
    const androidVersion = parseFloat(system.replace("Android ", ""));
    if (androidVersion < 4.4) {
      throw new Error("Android版本过低，需要4.4+");
    }
  } else if (platform === "ios") {
    const iosVersion = parseFloat(system.replace("iOS ", ""));
    if (iosVersion < 11) {
      throw new Error("iOS版本过低，需要11.0+");
    }
  }

  nfcMain = plus.android.runtimeMainActivity();
  var Intent = plus.android.importClass("android.content.Intent");
  var Activity = plus.android.importClass("android.app.Activity");
  var PendingIntent = plus.android.importClass("android.app.PendingIntent");
  var IntentFilter = plus.android.importClass("android.content.IntentFilter");
  nfcAdapter = plus.android.importClass("android.nfc.NfcAdapter");
  var _nfcAdapter = nfcAdapter.getDefaultAdapter(nfcMain);
  var ndef = new IntentFilter("android.nfc.action.NDEF_DISCOVERED");
  var tag = new IntentFilter("android.nfc.action.TAG_DISCOVERED");
  var tech = new IntentFilter("android.nfc.action.TECH_DISCOVERED");
  tech.addDataType("*/*");
  var intentFiltersArray = [ndef, tag, tech];

  var techListsArray = [
    ["android.nfc.tech.Ndef"],
    ["android.nfc.tech.IsoDep"],
    ["android.nfc.tech.NfcA"],
    ["android.nfc.tech.NfcB"],
    ["android.nfc.tech.NfcF"],
    ["android.nfc.tech.Nfcf"],
    ["android.nfc.tech.NfcV"],
    ["android.nfc.tech.NdefFormatable"],
    ["android.nfc.tech.MifareClassic"],
    ["android.nfc.tech.MifareUltralight"],
  ];

  var _intent = new Intent(nfcMain, nfcMain.getClass());
  _intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
  var pendingIntent = PendingIntent.getActivity(nfcMain, 0, _intent, 0);

  if (_nfcAdapter == null) {
    throw new Error("本设备不支持NFC!");
  } else if (!_nfcAdapter.isEnabled()) {
    throw new Error("NFC功能未打开!");
  } else {
    // nfcStatus.value = "NFC功能正常";
    _nfcAdapter.enableForegroundDispatch(
      nfcMain,
      pendingIntent,
      intentFiltersArray,
      techListsArray
    );
    return true;
  }
}

/**
 * 读取NFC标签数据
 * @param {number} sector - 要读取的扇区编号(0-15)
 * @param {string} sectorpwd - 要读取的验证密码(默认: "FFFFFFFFFFFF")
 * @param {number} block - 要读取的扇区编号(0为读取全部,1-4为数据块实际索引0-3)
 * @returns {Object} 包含读取结果的对象
 * @property {boolean} success - 读取是否成功
 * @property {string} id - 读取的数据(16进制字符串)
 * @property {string} data - 读取的数据(16进制字符串)
 * @throws {string} error - 错误信息(如果读取失败)
 */
function readNfc(sector = 0, sectorpwd = '', block = 0) {
  var mfc = null
  try {
    if (nfcAdapter === null) {
      throw new Error('NFC 未初始化，请先调用 initNFC()');
    }

    if (sector > 15) {
      throw new Error('超过扇区编号');
    }

    let _intent = nfcMain.getIntent();
    let _action = _intent.getAction();
    if (
      nfcAdapter.ACTION_NDEF_DISCOVERED === _action ||
      nfcAdapter.ACTION_TAG_DISCOVERED === _action ||
      nfcAdapter.ACTION_TECH_DISCOVERED === _action
    ) {
      let tagFromIntent = _intent.getParcelableExtra(nfcAdapter.EXTRA_TAG);
      let extraIDByte = _intent.getByteArrayExtra(nfcAdapter.EXTRA_ID);
      // 额外ID_extraID的数据和0扇区0块中的数据前8位一致.因此可直接使用
      // 可不用0扇区的密码
      const extraID = byteArrayToHexString(extraIDByte);
      // console.log(extraID)
      // 获取MifareClassic实例
      mfc = plus.android.importClass("android.nfc.tech.MifareClassic").get(tagFromIntent);
      try {
        if (!mfc.isConnected()) {
          plus.android.invoke(mfc, "connect");
        }
      } catch (e) {
        throw new Error("连接标签失败: " + e.message);
      }

      let nfcData = ""
      let sectorData = [];
      let tmpByte;
      let tmpblock = 0
      // 读取扇区密码为字节数组 如sectorpwd为空即使用默认密码
      let sectorpwdBytes = hexStringToByteArray(sectorpwd || "FFFFFFFFFFFF");
      // 验证读取扇区密码
      let sectorAuth = plus.android.invoke(
        mfc,
        "authenticateSectorWithKeyA",
        sector,
        sectorpwdBytes
      );
      // 验证读取扇区密码成功
      if (!sectorAuth) throw new Error("验证读取扇区扇区认证失败，密码错误");
      if (block > 0) {
        tmpblock = sector * 4 + (block - 1)
        tmpByte = plus.android.invoke(mfc, "readBlock", tmpblock);
        let tmpData = byteArrayToHexString(tmpByte)
        // console.log("块:" + tmpblock, "内容" + tmpData)
        sectorData.push.apply(sectorData, tmpByte);
      } else {
        // 读取全部数据 索引由0到3的数据
        for (var i = 0; i < 4; i++) {
          tmpblock = sector * 4 + i
          tmpByte = plus.android.invoke(mfc, "readBlock", tmpblock);
          let tmpData = byteArrayToHexString(tmpByte)
          // console.log("块:" + tmpblock, "内容" + tmpData)
          sectorData.push.apply(sectorData, tmpByte);
        }
      }

      nfcData = byteArrayToHexString(sectorData)
      // console.log("读取扇区:", sector, "读取数据:", nfcData);
      // console.log(JSON.stringify({
      // 	success: false,
      // 	id: nfcID,
      // 	extraID: extraID,
      // 	data: nfcData,
      // }))
      return {
        success: true,
        id: extraID,
        data: nfcData,
        message: "数据读取成功",
      };
    } else {
      throw new Error("未检测到有效的NFC标签");
    }
  } catch (e) {
    throw new Error("NFC读取错误:" + e.toString());
  } finally {
    if (mfc) {
      plus.android.invoke(mfc, "close");
    }
  }
}

/**
 * 写入 NFC 标签数据
 * @param {number} sector - 写入的扇区号
 * @param {string} password - 写入的扇区的密码
 * @param {string} content - 写入的内容（十六进制字符串）
 * @returns {object} 返回写入结果
 * @throws {string} 失败时抛出错误信息
 */
function writeNfc(sector = 1, password = '', content = '') {
  var mfc = null
  try {
    if (nfcAdapter === null) {
      throw new Error('NFC 未初始化，请先调用 initNFC()');
    }

    if (content === '') {
      throw new Error('写入数据不能为空');
    }
    if (sector > 15) {
      throw new Error('超过扇区编号');
    }

    let _intent = nfcMain.getIntent();
    let _action = _intent.getAction();
    if (
      nfcAdapter.ACTION_NDEF_DISCOVERED === _action ||
      nfcAdapter.ACTION_TAG_DISCOVERED === _action ||
      nfcAdapter.ACTION_TECH_DISCOVERED === _action
    ) {

      let tagFromIntent = _intent.getParcelableExtra(nfcAdapter.EXTRA_TAG);
      let extraIDByte = _intent.getByteArrayExtra(nfcAdapter.EXTRA_ID);
      const extraID = byteArrayToHexString(extraIDByte);
      // console.log(extraID)
      // 获取MifareClassic实例
      let mifareClassic = plus.android.importClass("android.nfc.tech.MifareClassic")
      mfc = mifareClassic.get(tagFromIntent);
      try {
        // 判断连接卡片
        if (!mfc.isConnected()) {
          plus.android.invoke(mfc, "connect");
        }
      } catch (e) {
        throw new Error("连接标签失败: " + e.message);
      }
      // 转换密码为字节数组
      let passwordBytes = hexStringToByteArray(password || "FFFFFFFFFFFF");

      // 验证扇区密码
      let auth = plus.android.invoke(
        mfc,
        "authenticateSectorWithKeyA",
        sector,
        passwordBytes
      );
      // console.log("扇区认证结果:", auth, "扇区:", sector);
      if (!auth) throw new Error("扇区认证失败，密码错误");
      // 获取扇区的第一个块索引
      let firstBlock = mfc.sectorToBlock(sector);
      // 每一个扇区获取最多的数据块
      let blockCount = mfc.getBlockCountInSector(sector);
      // console.log("写入扇区:", sector, "写入起始数据块:", firstBlock, "可写数据块", blockCount)
      // 如果写入是0扇区的话跳过不能写入0块的ID内容
      if (sector === 0) {
        firstBlock = firstBlock + 1; // 跳过第0块
        // 减去第一块和最后一块控制块
        blockCount = blockCount - 2
      } else {
        // 减去最后一块控制块
        blockCount = blockCount - 1
      }
      // 每个块的大小是16字节
      const blockSize = mifareClassic.BLOCK_SIZE;
      // 将内容转换为字节数组
      const contentBytes = hexStringToByteArray(content);
      // 确保数据长度不超过可用块的总大小
      const maxDataSize = blockCount * blockSize;
      // console.log("写入扇区:", sector, "写入起始数据块:", firstBlock, "可写数据块", blockCount, "可用块数据长度(字节):", maxDataSize, "写入数据长度(字节):", contentBytes.length)
      if (contentBytes.length > maxDataSize) {
        throw new Error(`数据长度超过可用块大小限制 (${maxDataSize} 字节)`);
      }

      // 分块写入数据
      for (let i = 0; i < blockCount; i++) {
        const startOffset = i * blockSize;
        const endOffset = Math.min(startOffset + blockSize, contentBytes.length);
        const blockData = contentBytes.slice(startOffset, endOffset);
        // 如果数据不足一个块，则填充剩余部分为0
        while (blockData.length < blockSize) {
          blockData.push(0x00);
        }
        const currentBlock = firstBlock + i;
        // console.log("扇区:", sector, "写入块:", currentBlock, "写入数据:", byteArrayToHexString(blockData));
        // plus.android.invoke(mfc, "writeBlock", currentBlock, blockData);
      }

      return {
        success: true,
        id: extraID,
        data: '',
        message: "数据写入成功",
      };

    } else {
      throw new Error("未检测到有效的NFC标签");
    }
  } catch (e) {
    throw new Error("NFC写入错误:" + e.toString());
  } finally {
    if (mfc) {
      plus.android.invoke(mfc, "close");
    }
  }
}

/**
 * 销毁NFC适配器，释放资源
 */
function destroyNfc() {
  if (nfcAdapter) {
    try {
      nfcAdapter.disableForegroundDispatch(nfcMain);
    } catch (error) {
      console.error("禁用NFC前台调度失败:", error);
    }
    nfcAdapter = null;
  }
}

/**
 * 将字节数组转换为16进制字符串
 * @param {Array} inarray - 字节数组
 * @returns {string} 转换后的16进制字符串
 */
function byteArrayToHexString(inarray) {
  let i, j, inn;
  const hex = [
    "0",
    "1",
    "2",
    "3",
    "4",
    "5",
    "6",
    "7",
    "8",
    "9",
    "A",
    "B",
    "C",
    "D",
    "E",
    "F",
  ];
  let out = "";
  for (j = 0; j < inarray.length; ++j) {
    inn = inarray[j] & 0xff;
    i = (inn >>> 4) & 0x0f;
    out += hex[i];
    i = inn & 0x0f;
    out += hex[i];
  }
  return out;
}

/**
 * 将16进制字符串转换为字节数组
 * @param {string} instr - 16进制字符串
 * @returns {Array} 转换后的字节数组
 */
function hexStringToByteArray(instr) {
  const hexA = [];
  let pos = 0;
  const len = instr.length / 2;
  for (let i = 0; i < len; i++) {
    const s = instr.substr(pos, 2);
    let v = parseInt(s, 16);
    if (v >= 128) v = v - 256;
    hexA.push(v);
    pos += 2;
  }
  return hexA;
}

// 暴露方法
export default {
  initNfc,
  readNfc,
  writeNfc,
  destroyNfc
};